package com.mystnihon.freeremote;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;

import org.apache.commons.io.IOUtils;

import android.app.Application;

import com.mystnihon.freeremote.data.GuideResultData;
import com.octo.android.robospice.SpiceService;
import com.octo.android.robospice.persistence.CacheManager;
import com.octo.android.robospice.persistence.binary.InFileInputStreamObjectPersister;
import com.octo.android.robospice.persistence.exception.CacheLoadingException;
import com.octo.android.robospice.persistence.exception.CacheSavingException;
import com.octo.android.robospice.persistence.file.InFileObjectPersister;
import com.octo.android.robospice.persistence.string.InFileStringObjectPersister;

public class FreeRemoteSpiceService extends SpiceService {

    @Override
    public CacheManager createCacheManager(Application application) {
        CacheManager cacheManager = new CacheManager();

        // init
        InFileStringObjectPersister inFileStringObjectPersister = new InFileStringObjectPersister(application);
        InFileInputStreamObjectPersister inFileInputStreamObjectPersister = new InFileInputStreamObjectPersister(application);
        InFileGuideResultPersister lInFileGuideResultPersister = new InFileGuideResultPersister(application);

        inFileStringObjectPersister.setAsyncSaveEnabled(true);
        inFileInputStreamObjectPersister.setAsyncSaveEnabled(true);

        cacheManager.addPersister(inFileStringObjectPersister);
        cacheManager.addPersister(inFileInputStreamObjectPersister);
        cacheManager.addPersister(lInFileGuideResultPersister);
        return cacheManager;
    }

    @Override
    public int getThreadCount() {
        return 2;
    }

    private class InFileGuideResultPersister extends InFileObjectPersister<GuideResultData> {

        public InFileGuideResultPersister(Application application) {
            super(application, GuideResultData.class);
        }

        @Override
        public GuideResultData loadDataFromCache(Object cacheKey, long maxTimeInCache) throws CacheLoadingException {
            File file = getCacheFile(cacheKey);
            if (isCachedAndNotExpired(file, maxTimeInCache)) {
                ObjectInputStream inputStream;
                GuideResultData data = null;
                try {
                    inputStream = new ObjectInputStream(new FileInputStream(file));
                    data = (GuideResultData) inputStream.readObject();
                } catch (StreamCorruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                if (data == null) {
                    throw new CacheLoadingException(String.format("Found the file %s but could not decode file.", file.getAbsolutePath()));
                }
                return data;
            }
            return null;
        }

        @Override
        public GuideResultData saveDataToCacheAndReturnData(GuideResultData data, Object cacheKey) throws CacheSavingException {
            ObjectOutputStream out = null;

            try {
                File cacheFile = getCacheFile(cacheKey);
                out = new ObjectOutputStream(new FileOutputStream(cacheFile));
                out.writeObject(data);
                return data;
            } catch (IOException e) {
                throw new CacheSavingException(e);
            } finally {
                IOUtils.closeQuietly(out);
            }
        }

    }
}
